//	System include files
#include <p18f452.h>			//Board specific header
#include <usart.h>				//Serial functions
#include <stdio.h>
#include <stdlib.h>
#include <adc.h>`
#include <delays.h>
#include <string.h>
#include "serial.h"	//header


//System constant definitions
#define TBUFFSIZE 	0x50			//transmit buffer of 80 size

// for demo board*/
/******************************************************************/
#define BAUDRATE 	25				//For baudrate of 9600 on 4MHz board
#define	BRGH_RATE USART_BRGH_HIGH
/*******************************************************************/


// for mini board
/***********************************************************/
//#define BAUDRATE	0x40			//For baudrate of 9600 on 40MHz board
//#define	BRGH_RATE USART_BRGH_LOW
/***********************************************************/
#define BUFFSIZE 	0x8				//To hold buffer of size 8
#define ENTER	    0xD				//ENTER key
#define LINEFEED	0xA				//line feed key


#define	SET	1					//bitwise set
#define CLEAR 0					//bitwise clear

//***************************************************
//Function prototypes
void hisr_rx232(void);
void hisr_tx232(void);
void Serial_Setup (void);
void Serial_SetupInterrupt (void);
unsigned char Serial_ReadBuffer(void);
void Serial_AppendString (unsigned char *string);

//***************************************************


#pragma code
//System variables
/** @brief Recieve buffer for temp storage */
char receive_buffer[BUFFSIZE];

char rdata_end=0,rdata_start=0;
char transmit_buffer[TBUFFSIZE];
char tdata_end=0,tdata_start=0;
unsigned char appended=0;



/**
@brief    Serial_Setup() - setup the serial module
@param	  none
@return   void
*/
void Serial_Setup (void)
{
	OpenUSART(	USART_TX_INT_ON &		//enable transmit interrupt
		USART_RX_INT_ON &				//enable receive interrupt
		USART_ASYNCH_MODE &				//asynchronous mode
		USART_EIGHT_BIT &				//8 bit transmission
		USART_CONT_RX &					//continuous receive
		BRGH_RATE,						//high baud rate
		BAUDRATE);						//set baud rate to 9600
	TRISCbits.TRISC7=SET;				//set to allow serial input
	TRISCbits.TRISC6=CLEAR;				//set to allow serial output
}
/*
@brief    Serial_Setup_Interrupt() - setup the serial interrupts
@param	  none
@return   void
*/
void Serial_Setup_Interrupt (void)
{
	
	IPR1bits.TXIP=CLEAR;		//set transmit to low priority
	PIR1bits.TXIF=CLEAR;		//clear transmit flag
	IPR1bits.RCIP=CLEAR;		//set receive to low priority
	PIE1bits.TXIE=CLEAR;		//disable transmit interrupts
	
	
	/*global interup requirements*/
	RCONbits.IPEN=SET;			//enable interrupt priority
	INTCONbits.PEIE=SET;		//enable peripheral interrupts
	INTCONbits.GIE=SET;   		//enable global interrupts

}	

/**
@brief    hisr_rx232() - interrupt to receive and store input
@param	  none
@return   void
*/
void hisr_rx323(void)
{
//	if (PIR1bits.RCIF)					//check if receive interrupt
//  {
		receive_buffer[rdata_end]=RCREG;//get byte
		rdata_end++;					//increment pointer
		if(rdata_end==BUFFSIZE)			//end of buffer
		{
			rdata_end=0;				//return to beginning
  	}
 //  }
}

/**
@brief    hisr_tx232() - interrupt to transmit one byte
@param	  none
@return   void
*/
void hisr_tx232(void)
{
 //  if (PIR1bits.TXIF && PIE1bits.TXIE)		//check if transmit interrupt
 //  {
		TXREG=transmit_buffer[tdata_start];	//transmit next byte
		tdata_start++;
		if (tdata_start==TBUFFSIZE)			//end of buffer
		{
			tdata_start=0;					//back to beginning
		}
		if (tdata_start==tdata_end)
		{
			appended=0;						//enable more inputs
			PIE1bits.TXIE=CLEAR;			//disable transmit interrupts, due to end of data
		}
 //  }
}

/**
@brief    Serial_ReadBuffer() - function to obtain next byte in data
@param	  none
@return   unsigned char
*/
unsigned char Serial_ReadBuffer(void)
{
	unsigned char byte;
	if (rdata_end != rdata_start)					//check if there is receive data
	{
		byte = receive_buffer[rdata_start];		//get next byte
		rdata_start++;							//increment pointer
		if (rdata_start==BUFFSIZE)				//end of buffer
		{
			rdata_start=0;						//return to beginning
		}
		return byte;
	}
	else										//no receive data
	{
		return 0;
	}
}

/**
@brief    Serial_AppendString() - function to append string to output buffer
@param	  string
@return   void
*/
void Serial_AppendString ( unsigned char *string)
{
	unsigned char string_point=0;
	while(appended);										//check if still transmitting
	while(*(string)!=0)
	{
		transmit_buffer[tdata_end]=*(string);	//load next value
		tdata_end++;							
		string++;
		//while(tdata_end==tdata_start && PIE1bits.TXIE);			//check if transmission is about to lap data input				
		if (tdata_end==TBUFFSIZE)				//end of buffer
		{
			tdata_end=0;						//back to beginning
		}
	}
	appended=SET;
	PIE1bits.TXIE=SET;					//enable transmit interrupts
}

char *strrev( char *s,int n)
{
       int i=0;
       while (i<n/2)
     	{
               *(s+n) = *(s+i);       //uses the null character as the temporary storage.
               *(s+i) = *(s + n - i -1);
               *(s+n-i-1) = *(s+n);
               i++;
       }
       *(s+n) = '\0';

       return s;
}
/**
@brief    int_2_string() - function to convert an unsigned in to an ascii string
@param	  unsigned int n (interger to be converted), string c (string to store the ascii representation pf n)
@return   void
*/ 
	
void int_2_string(unsigned int n, char s[])
 {
     unsigned int i, sign;
     int length = 0;
 

     i = 0;
     do {       /* generate digits in reverse order */
         s[i++] = n % 10 + '0';   /* get next digit */
     } while ((n /= 10) > 0);     /* delete it */
     if (sign < 0)
         s[i++] = '-';
     s[i] = '\0';
     length = strlen(s);
     s = strrev(s,length);
 }




/**
@brief    checkpin() - function to check pin
@param	  string of pin code
@return   1 if correct, 0 if incorrect
*/
unsigned char checkpin (unsigned char pincode[])
{
	if (pincode[4]==ENTER)
	{
		if (pincode[0]=='3' && pincode[1]=='7' && pincode[2]=='0' && pincode[3]=='0')
		{
			return 1;
		}
	}
	else 
	{
		return 0;
	}
}
